package org.jtb.flickrportlet;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.portlet.ActionRequest;
import javax.portlet.PortletException;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.portlet.PortletFileUpload;
import org.apache.log4j.Logger;
import org.jtb.quickr.AuthResponse.Token;
import org.jtb.quickr.QuickrException;
import org.jtb.quickr.UploadCriteria;
import org.jtb.quickr.UploadService;

public class PhotoUploader {
    private static Logger logger = Logger.getLogger(PhotoUploader.class.getName());
    
    private ActionRequest request;
    private Token token;
    
    public PhotoUploader(ActionRequest request, Token token) {
        this.request = request;
        this.token = token;
    }
    
    public boolean isUploadRequest() {
        boolean multipart = PortletFileUpload.isMultipartContent(request);
        return multipart;
    }
    
    public boolean upload() throws IOException, QuickrException, PortletException {
        if (!isUploadRequest()) {
            throw new PortletException("not an upload request");
        }

        // were any files uploaded?
        boolean uploaded = false;
        
        FileItemFactory factory = new DiskFileItemFactory();
        PortletFileUpload upload = new PortletFileUpload(factory);
        List items;
        try {
            items = upload.parseRequest(request);
        } catch (FileUploadException fue) {
            throw new PortletException("error parsing upload request", fue);
        }
        if (logger.isDebugEnabled()) {
            logger.debug("number of items received: " + items.size());
        }
        
        Iterator<FileItem> iter = items.iterator();
        Map<String,String> params = new HashMap<String,String>();
        Map<String,File> files = new HashMap<String,File>();
        
        // split items into parameters and files
        
        while (iter.hasNext()) {
            FileItem item = (FileItem)iter.next();
            String fieldName = item.getFieldName();
            
            if (item.isFormField()) {
                String val = item.getString();
                if (val != null && val.length() > 0) {
                    params.put(fieldName, val);
                    if (logger.isDebugEnabled()) {
                        logger.debug("got form field: " + fieldName + " val: " + val);
                    }
                }
            } else {
                long size = item.getSize();
                if (size > 0) {
                    File tmpFile = File.createTempFile("flickrportlet", ".tmp");
                    try {
                        item.write(tmpFile);
                    } catch (Exception e) {
                        throw new PortletException("error writing temp upload file", e);
                    }
                    files.put(fieldName, tmpFile);
                    params.put(fieldName, getTitle(item.getName()));
                    if (logger.isDebugEnabled()) {
                        logger.debug("wrote temp file for field: " + fieldName + " to file: " + tmpFile);
                    }
                }
            }
        }
        
        String submit = params.get("submit");        
        if (submit != null) {
            // user submitted, did not cancel
            if (logger.isDebugEnabled()) {
                logger.debug("using token: " + token);
            }
            
            UploadCriteria uc = new UploadCriteria();
            UploadService us = new UploadService();
            
            for (Iterator<String> i = files.keySet().iterator(); i.hasNext(); ) {
                // upload each file
                String name = i.next();
                if (logger.isDebugEnabled()) {
                    logger.debug("got name: " + name);
                }
                
                File f = files.get(name);
                if (logger.isDebugEnabled()) {
                    logger.debug("got file: " + f);
                }
                uc.setPhoto(f);
                
                String title = params.get(name+"_title");
                if (title == null) {
                    // if no title was given by user,
                    // use file name minus extension
                    title = params.get(name);
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("got title: " + title);
                }
                uc.setTitle(title);
                
                us.upload(token, uc);
                uploaded = true;;
            }
        }

        return uploaded;        
    }
    
    /**
     * Get a photo title from an absolute file path.
     * This method strips off the leading path,
     * and any extension.
     */
    private static String getTitle(String path) {
        File f = new File(path);
        String title = f.getName();
        int i = title.lastIndexOf(".");
        if (i != -1) {
            title = title.substring(0, i);
        }
        
        return title;
    }
}
